﻿using System.IO;
using System.Runtime.Serialization;
using System.Xml;

namespace JelleDruyts.Windows
{
    /// <summary>
    /// Provides serialization services.
    /// </summary>
    public static class SerializationProvider
    {
        #region Fields

        private static XmlWriterSettings xmlWriterSettings = new XmlWriterSettings { Indent = true, NewLineHandling = NewLineHandling.Entitize };

        #endregion

        #region Methods

        /// <summary>
        /// Reads a serialized object from a file.
        /// </summary>
        /// <typeparam name="T">The type of the object to read.</typeparam>
        /// <param name="fileName">The file name of the serialized object.</param>
        /// <returns>The deserialized object.</returns>
        public static T Read<T>(string fileName)
        {
            var serializer = new DataContractSerializer(typeof(T));
            using (var stream = File.OpenRead(fileName))
            {
                return (T)serializer.ReadObject(stream);
            }
        }

        /// <summary>
        /// Writes a serialized object to a file.
        /// </summary>
        /// <typeparam name="T">The type of the object to write.</typeparam>
        /// <param name="obj">The object to serialize.</param>
        /// <param name="fileName">The file name of the serialized object.</param>
        public static void Write<T>(T obj, string fileName)
        {
            var serializer = new DataContractSerializer(obj.GetType());
            using (var writer = XmlWriter.Create(fileName, xmlWriterSettings))
            {
                serializer.WriteObject(writer, obj);
            }
        }

        /// <summary>
        /// Creates a deep clone of an object by serializing and deserializing it.
        /// </summary>
        /// <typeparam name="T">The type of the object to clone.</typeparam>
        /// <param name="obj">The object to clone.</param>
        /// <returns>A deep clone of the object.</returns>
        public static T Clone<T>(T obj)
        {
            var serializer = new DataContractSerializer(obj.GetType());
            using (var stream = new MemoryStream())
            {
                serializer.WriteObject(stream, obj);
                stream.Position = 0;
                return (T)serializer.ReadObject(stream);
            }
        }

        #endregion
    }
}
